// Object.defineProperty() 定义属性的方法
// Object.defineProperty(obj,prop,descriptor)
function defineProperty() {
    var _obj = {}
        // Object.defineProperty(_obj, 'a', {
        //         value: 1
        //     })
        // 设置多个属性值
        // 使用defineProperty创建的属性不可修改，不可枚举，不可删除
    Object.defineProperties(_obj, {
        a: {
            value: 1,
            //可写，默认值false，设置为true表示可写的
            writable: true,
            //可否枚举，默认值为false
            enumerable: true,
            //是否可配置，默认值false
            configurable: true
        },
        b: {
            value: 2
        },
    })

    return _obj
}
var obj = defineProperty();
obj.a = 5
obj.b = 5
console.log(obj);
for (var k in obj) {
    console.log(k + ':' + obj[k]); //a:5
}
delete obj.a;
console.log(obj);
console.log('-----------------------分割线----------------------');

function defineProperty1() {
    var _obj = {};
    var a = 1;
    // 每个属性定义的时候有getter setter机制
    Object.defineProperties(_obj, {
        a: {
            // value和writable与get set不能同时设置，冲突
            get() {
                return '"a"\'s value is ' + a + '.';
            },
            set(newVal) {
                console.log(newVal + ':' + 'newVal');
                a = newVal
                var oP = document.getElementsByTagName('p')[0]
                oP.innerHTML = a;
            }
        },
        b: {

        }
    })
    return _obj
}
var obj = defineProperty1();
obj.a = 2
console.log(obj.a);
console.log('-----------------------分割线----------------------');
// 数据劫持
// 在数据获取、设置的时候，通过get和set方法对数据的存取值，进行逻辑上的扩展
function DataArr() {
    var _val = null,
        _arr = [];
    Object.defineProperty(this, 'val', {
        get: function() {
            return _val;
        },
        set: function(newVal) {
            _val = newVal;
            _arr.push({
                val: _val
            });
            console.log(newVal + '：' + "newVal");
        }
    });
    this.getArr = function() {
        return _arr;
    }
}
var dataArr = new DataArr();
dataArr.val = 123;
dataArr.val = 133;
console.log(dataArr.getArr());
console.log('-----------------------分割线----------------------');

class Compute {
    plus(a, b) {
        return a + b;
    }
    minus(a, b) {
        return a - b;
    }
    mul(a, b) {
        return a * b;
    }
    div(a, b) {
        return a / b;
    }
}

class Calculator extends Compute {
    constructor(doc) {
        super()
        console.log(doc);
        const oCal = doc.getElementsByClassName('J_calculator')[0];
        this.fInput = oCal.getElementsByTagName('input')[0];
        this.sInput = oCal.getElementsByTagName('input')[1];
        this.oBtnGroup = oCal.getElementsByClassName('btn-group')[0];
        this.oBtnItem = this.oBtnGroup.getElementsByTagName('button');
        this.oResult = oCal.getElementsByClassName('result')[0]
        this.data = this.defineData();
        this.btnIdx = 0;
        console.log(this.data);
    }
    init() {
        this.bindEvent();
    }
    bindEvent() {
        this.oBtnGroup.addEventListener('click', this.onFieldBtnClick.bind(this))
        this.fInput.addEventListener('input', this.onNumberInput.bind(this))
        this.sInput.addEventListener('input', this.onNumberInput.bind(this))

    }
    defineData() {
        let _obj = {},
            fNumber = 0,
            sNumber = 0,
            field = 'plus';
        const _self = this;
        Object.defineProperties(_obj, {
            fNumber: {
                get() {
                    return fNumber;
                },
                set(newVal) {
                    fNumber = newVal;
                    _self.computeResult(fNumber, sNumber, field)
                    console.log(fNumber);
                }
            },
            sNumber: {
                get() {
                    return sNumber
                },
                set(newVal) {
                    sNumber = newVal;
                    _self.computeResult(fNumber, sNumber, field)
                    console.log(sNumber);
                }
            },
            field: {
                get() {
                    return field
                },
                set(newVal) {
                    field = newVal;
                    _self.computeResult(fNumber, sNumber, field)
                    console.log(field);
                }
            }
        })
        return _obj
    }
    onFieldBtnClick(ev) {
        const e = ev || window.event,
            tar = e.target || e.srcElement,
            tagName = tar.tagName.toLowerCase();
        tagName === 'button' && this.fieldUpdate(tar);

    }
    fieldUpdate(tar) {
        this.oBtnItem[this.btnIdx].className = '';
        this.btnIdx = [].indexOf.call(this.oBtnItem, tar);
        tar.className = 'current',
            this.data.field = tar.getAttribute('data-field')
    }
    onNumberInput(ev) {
        const e = ev || window.event,
            tar = e.target || e.srcElement,
            className = tar.className,
            val = Number(tar.value.replace(/\s+/g, '')) || 0;
        switch (className) {
            case 'f-input':
                this.data.fNumber = val
                break;
            case 's-input':
                this.data.sNumber = val;
                break;
            default:
                break;
        }
    }
    computeResult(fNumber, sNumber, field) {
        console.log(this[field](fNumber, sNumber));
        this.oResult.innerText = this[field](fNumber, sNumber)
    }
}

new Calculator(document).init();